package com.basic.library.utils;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.DownloadManager;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.core.content.FileProvider;

import com.basic.library.R;
import com.basic.library.base.BaseConstants;
import com.basic.library.utils.toast.ToastCompat;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * @author yj
 * @description
 */
public class DownloadManagerUtil {
    private Context mContext;
    private long downloadId;
    private Handler mHandler = new Handler(Looper.getMainLooper());
    private boolean showDialog;
    private DownloadChangeObserver observer;
    private final Uri CONTENT_URI = Uri.parse("content://downloads/my_downloads");
    private File file;

    public DownloadManagerUtil(Context mContext) {
        this.mContext = mContext;
    }

    /**
     * @param url
     * @param fileName   文件名(包括后缀名)
     * @param mHandler
     * @param showDialog
     */
    public void downloadFile(@NonNull String url, String fileName, @NonNull Handler mHandler, boolean showDialog) {
        this.showDialog = showDialog;
        this.mHandler = mHandler;
        downLoad(url, fileName);
    }

    /**
     * 系统自带下载管理器 下载 （checkDownloadManagerEnable可能报错？？？？？）
     *
     * @param url
     * @param title
     * @param desc
     * @param mHandler
     * @param showDialog
     */
    public void downloadFile1(String url, String title, String desc, Handler mHandler, boolean showDialog) {
        this.showDialog = showDialog;
        this.mHandler = mHandler;
        if (checkDownloadManagerEnable()) {
            if (downloadId != 0L) {
                clearCurrentTask(downloadId); // 先清空之前的下载
            }
            downloadId = download(url, title, desc);
            //更新UI
            observer = new DownloadChangeObserver(new Handler());
            mContext.getContentResolver().registerContentObserver(CONTENT_URI, true, observer);
        } else {
            Toast.makeText(mContext, "请开启下载管理器", Toast.LENGTH_SHORT).show();
        }
    }

    /**
     * 可能会出错Cannot update URI: content://downloads/my_downloads/-1
     * 检查下载管理器是否被禁用
     */
    Boolean checkDownloadManagerEnable() {
        try {
            int state = mContext.getPackageManager().getApplicationEnabledSetting("com.android.providers.downloads");
            if (state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED
                    || state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER
                    || state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
                String packageName = "com.android.providers.downloads";
                try {
                    Intent intent = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                    intent.setData(Uri.parse("package:" + packageName));
                    mContext.startActivity(intent);
                } catch (ActivityNotFoundException e) {
                    e.printStackTrace();
                    Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS);
                    mContext.startActivity(intent);
                }
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    Long download(String url, String title, String desc) {
        MyLog.p("开始下载");
        try {
            Uri uri = Uri.parse(url);
            DownloadManager.Request req = new DownloadManager.Request(uri);
            //设置允许使用的网络类型，这里是移动网络和wifi都可以
            req.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE | DownloadManager.Request.NETWORK_WIFI);
            //下载中和下载完后都显示通知栏
            req.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);

            //设置文件的保存的位置[三种方式]
            // 第一种 file:///storage/emulated/0/Android/data/your-package/files/Download/update.apk
//            req.setDestinationInExternalFilesDir(mContext, Environment.DIRECTORY_DOWNLOADS, "$title.apk");
            //第二种 file:///storage/emulated/0/Download/update.apk

            req.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, BaseConstants.Save_RootFile + ".apk");
            //第三种 自定义文件路径
//        req.setDestinationUri()

            //禁止发出通知，既后台下载
            if (showDialog)
                req.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
            //通知栏标题
            req.setTitle(title);
            //通知栏描述信息
            req.setDescription(desc);
            //设置类型为.apk
            req.setMimeType("application/vnd.android.package-archive");
            // 设置为可被媒体扫描器找到
            req.allowScanningByMediaScanner();
            // 设置为可见和可管理
            req.setVisibleInDownloadsUi(true);
            //获取下载任务ID
            DownloadManager dm = (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE);
            return dm.enqueue(req);
        } catch (Exception e) {
            Toast.makeText(mContext, "找不到下载文件", Toast.LENGTH_SHORT).show();
            return -1L;
        }
    }

    public void downLoad(final String path, String fileName) {
        if (fileName == null) {
            String[] splits = path.split("/");
            fileName = splits[splits.length - 1];
        }
        String finalFileName = fileName;
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    URL url = new URL(path);
                    HttpURLConnection con = (HttpURLConnection) url.openConnection();
//                    con.setReadTimeout(5000);
                    con.setConnectTimeout(5000);
                    con.setRequestProperty("Charset", "UTF-8");
                    con.setRequestMethod("GET");
                    if (con.getResponseCode() == 200) {
                        InputStream is = con.getInputStream();//获取输入流
                        FileOutputStream fileOutputStream = null;//文件输出流
                        if (is != null) {
                            file = new File(mContext.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS) + "/" + finalFileName);
                            System.out.println(file.getAbsolutePath());
//                            file = new File(Environment.getExternalStorageDirectory() + "/" + Environment.DIRECTORY_DOWNLOADS + "/" + finalFileName);
                            if (file.exists())
                                file.delete();
                            fileOutputStream = new FileOutputStream(file);//指定文件保存路径，代码看下一步
                            byte[] buf = new byte[4096];
                            int ch;
                            long t = 0;
                            while ((ch = is.read(buf)) != -1) {
                                t += ch;
                                MyLog.p("下载进度：" + t + "/" + con.getContentLength());
                                final int pro = BigDecimal.valueOf(t * 100D).divide(BigDecimal.valueOf(con.getContentLength() * 1D), 2, RoundingMode.HALF_UP).intValue();
                                mHandler.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        onShow(mContext, pro);
                                        if (100 == pro && finalFileName.endsWith(".apk")) {
                                            installApk0(file);
                                        }
                                    }
                                });
                                fileOutputStream.write(buf, 0, ch);//将获取到的流写入文件中
                            }
                        }
                        if (fileOutputStream != null) {
                            fileOutputStream.flush();
                            fileOutputStream.close();
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            onShow(mContext, -1);
                        }
                    });
                }
            }
        }).start();
    }

    /**
     * 下载前先移除前一个任务，防止重复下载
     *
     * @param downloadId
     */
    void clearCurrentTask(Long downloadId) {
        DownloadManager dm = (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE);
        try {
            dm.remove(downloadId);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private int getDownloadPercent(long downloadId) {
        DownloadManager.Query query = new DownloadManager.Query().setFilterById(downloadId);
        DownloadManager dm = (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE);
        Cursor c = dm.query(query);
        if (c.moveToFirst()) {
            int downloadBytesIdx = c.getColumnIndexOrThrow(
                    DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR);
            int totalBytesIdx = c.getColumnIndexOrThrow(
                    DownloadManager.COLUMN_TOTAL_SIZE_BYTES);
            long totalBytes = c.getLong(totalBytesIdx);
            long downloadBytes = c.getLong(downloadBytesIdx);
            onShow(mContext, (int) (downloadBytes * 100f / totalBytes));
            MyLog.p(downloadId + "进度-" + totalBytes + "---" + downloadBytes);
            if (totalBytes == downloadBytes) {
//                installApk(downloadId);
            }
            return (int) (downloadBytes * 100f / totalBytes);
        }
        return 0;
    }

    class DownloadChangeObserver extends ContentObserver {

        public DownloadChangeObserver(Handler handler) {
            super(handler);
        }

        @Override
        public void onChange(boolean selfChange) {
            super.onChange(selfChange);
            getDownloadPercent(downloadId);
        }
    }

    private void installApk(Long downloadId) {
        DownloadManager dm = (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE);
        Intent install = new Intent(Intent.ACTION_VIEW);
        Uri downloadFileUri = dm.getUriForDownloadedFile(downloadId);
        if (downloadFileUri != null) {
            install.setDataAndType(downloadFileUri, "application/vnd.android.package-archive");
            if ((Build.VERSION.SDK_INT >= 24)) {//判读版本是否在7.0以上
                install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //添加这一句表示对目标应用临时授权该Uri所代表的文件
            }
            install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            if (install.resolveActivity(mContext.getPackageManager()) != null) {
//                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && mContext.getPackageManager().canRequestPackageInstalls())
                mContext.startActivity(install);
            } else {
                Toast.makeText(mContext, "自动安装失败，请手动安装", Toast.LENGTH_SHORT).show();
            }
        } else {
        }
    }

    private void installApk0(File file) {
        Intent install = new Intent(Intent.ACTION_VIEW);
        Uri apkUri = Uri.fromFile(file);
        if ((Build.VERSION.SDK_INT >= 24)) {//判读版本是否在7.0以上
            apkUri = FileProvider.getUriForFile(mContext, mContext.getPackageName() + ".provider", file);
            install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //添加这一句表示对目标应用临时授权该Uri所代表的文件
        }
        install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        install.setDataAndType(apkUri, "application/vnd.android.package-archive");
        if (install.resolveActivity(mContext.getPackageManager()) != null) {
//                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && mContext.getPackageManager().canRequestPackageInstalls())
            mContext.startActivity(install);
        } else {
            Toast.makeText(mContext, "自动安装失败，请手动安装", Toast.LENGTH_SHORT).show();
        }
    }

    public void onDestroy() {
        if (observer != null) {
            mContext.getContentResolver().unregisterContentObserver(observer);
        }
    }


    ProgressBar bar;

    private AlertDialog dialog;
    private TextView progress;
    private int Pro;

    public void onShow(Context context, int pro) {
        if (pro < 0)
            ToastCompat.show("下载失败");
        if (!showDialog) {
            Message message = new Message();
            message.what = pro;
            message.obj = file.getAbsolutePath();
            mHandler.sendMessage(message);
            return;
        }
        if (Pro == pro) return;
        Pro = pro;
        if (dialog == null) {
            AlertDialog.Builder builder = new AlertDialog.Builder(context);
            View view = ((Activity) context).getLayoutInflater().inflate(R.layout.dialog_download, null);
            bar = view.findViewById(R.id.pb_update);
            progress = view.findViewById(R.id.progress);
            bar.setProgress(0);
            builder.setView(view);
            dialog = builder.create();
            dialog.setCanceledOnTouchOutside(false);
            dialog.setCancelable(false);
            dialog.show();
        }
        bar.setProgress(pro);
        progress.setText(pro + "%");
        if (pro == 100 && dialog.isShowing())
            dialog.dismiss();
    }
}
